package com.tubeilike.entity;

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
import com.google.appengine.api.datastore.Text;
import com.google.gdata.data.youtube.VideoEntry;
import com.google.gdata.util.ServiceException;
import com.tubeilike.entity.Tag;
import com.tubeilike.entity.Tube;
import com.tubeilike.model.TagModel;
import com.tubeilike.util.JavaCacheHandle;
import com.tubeilike.util.StringHelper;

@PersistenceCapable
public class Tube {

	@PrimaryKey
	@Persistent
	private String tubeId; // id from youtube, use to get video.
	@Persistent
	private String categoryAlias;
	@Persistent
	private Date published; // created date from youtube.
	@Persistent
	private Date updated; // update date.
	@Persistent
	private Text title; // video title.
	@Persistent
	private Text description; // video description.
	@Persistent
	private Text alias; // video alias, from title replace string.
	@Persistent
	private Text thumbImageUrl; // image will display in search result.
	@Persistent
	private Long duration; // video duration, how many seconds.
	@Persistent
	private Text totalTime; // calculate by duration. example : 2:36:30.
	@Persistent
	private List<Text> keywords; // video tags.
									// videoEntry.getMediaGroup().getKeywords().getKeywords()
	@Persistent
	private List<Text> otherKeywords; // video other tags.
	@Persistent
	private List<Text> comments;
	@Persistent
	private Text totalComment; // comment count;
	@Persistent
	private String authorUrl; // author url.
	@Persistent
	private long viewCount; // total view of video.
	@Persistent
	private long catePosition; // where to display video in category.
	@Persistent
	private int status;

	public long getCatePosition() {
		return catePosition;
	}

	public void setCatePosition(long catePosition) {
		this.catePosition = catePosition;
	}

	public String getTubeId() {
		return tubeId;
	}

	public void setTubeId(String tubeId) {
		this.tubeId = tubeId;
	}

	public String getCategoryAlias() {
		return categoryAlias;
	}

	public void setCategoryAlias(String categoryAlias) {
		this.categoryAlias = categoryAlias;
	}

	public Date getPublished() {
		return published;
	}

	public void setPublished(Date published) {
		this.published = published;
	}

	public Date getUpdated() {
		return updated;
	}

	public void setUpdated(Date updated) {
		this.updated = updated;
	}

	public Text getTitle() {
		return title;
	}

	public void setTitle(Text title) {
		this.title = title;
	}

	public String getSubTitle() {
		if (this.title.getValue().length() > 33) {
			String[] split = this.title.getValue().substring(0, 33).split(" ");
			String subTitle = "";
			for (int i = 0; i < (split.length - 1); i++) {
				subTitle += " " + split[i];
			}
			if (subTitle.length() > 33) {
				subTitle = subTitle.substring(0, 33);
			}
			return (subTitle + "...");
		} else {
			return this.title.getValue();
		}
	}

	public Text getDescription() {
		return description;
	}

	public void setDescription(Text description) {
		this.description = description;
	}

	public Text getAlias() {
		return alias;
	}

	public void setAlias(Text alias) {
		this.alias = alias;
	}

	public Text getThumbImageUrl() {
		return thumbImageUrl;
	}

	public void setThumbImageUrl(Text thumbImageUrl) {
		this.thumbImageUrl = thumbImageUrl;
	}

	public Long getDuration() {
		return duration;
	}

	public void setDuration(Long duration) {
		this.duration = duration;
	}

	public Text getTotalTime() {
		return totalTime;
	}

	public void setTotalTime(Text totalTime) {
		this.totalTime = totalTime;
	}

	public List<Text> getKeywords() {
		return keywords;
	}

	public void setKeywords(List<Text> keywords) {
		this.keywords = keywords;
	}

	public List<Text> getOtherKeywords() {
		return otherKeywords;
	}

	public void setOtherKeywords(List<Text> otherKeywords) {
		this.otherKeywords = otherKeywords;
	}

	public List<Text> getComments() {
		return comments;
	}

	public void setComments(List<Text> comments) {
		this.comments = comments;
	}

	public Text getTotalComment() {
		return totalComment;
	}

	public void setTotalComment(Text totalComment) {
		this.totalComment = totalComment;
	}

	public String getAuthorUrl() {
		return authorUrl;
	}

	public void setAuthorUrl(String authorUrl) {
		this.authorUrl = authorUrl;
	}

	public long getViewCount() {
		return viewCount;
	}

	public void setViewCount(long viewCount) {
		this.viewCount = viewCount;
	}

	public int getStatus() {
		return status;
	}

	public void setStatus(int status) {
		this.status = status;
	}

	/*
	 * This method tranform only important field VideoEntry (from youtube api)
	 * to Tube
	 */
	public void transformHalfVideoEntry(VideoEntry entry) {
		this.tubeId = (entry.getMediaGroup().getVideoId());
		if (entry.getMediaGroup().getThumbnails() != null
				&& entry.getMediaGroup().getThumbnails().size() > 1) {
			this.thumbImageUrl = (new Text(entry.getMediaGroup()
					.getThumbnails().get(1).getUrl()));
		}
		this.title = (new Text(entry.getMediaGroup().getTitle()
				.getPlainTextContent()));

		if (entry.getMediaGroup().getDescription() != null) {
			this.description = (new Text(entry.getMediaGroup().getDescription()
					.getPlainTextContent()));
		}
		this.alias = (new Text(StringHelper.getAliasByLanguage(this.getTitle()
				.getValue())));

		this.authorUrl = (entry.getAuthors().get(0).getUri());
		if (entry.getStatistics() != null) {
			this.viewCount = entry.getStatistics().getViewCount();
		}
		if (entry.getMediaGroup().getDuration() != null) {
			Long duration = entry.getMediaGroup().getDuration();
			int hours = (int) (duration / 3600);
			int remainder = (int) (duration - hours * 3600);
			int minutes = remainder / 60;
			remainder = remainder - minutes * 60;
			int second = remainder;
			this.duration = (duration);
			this.totalTime = (new Text(((hours > 0) ? (hours + ":") : "")
					+ ((minutes > 9) ? minutes : ("0" + minutes)) + ":"
					+ ((second > 9) ? second : ("0" + second))));
		}
	}

	/*
	 * This method tranform VideoEntry (from Gdata - Youtube api) to Tube
	 * Object.
	 */
	public void transformVideoEntry(VideoEntry videoEntry)
			throws MalformedURLException, IOException, ServiceException {
		// core.
		this.tubeId = (videoEntry.getMediaGroup().getVideoId());
		if (videoEntry.getMediaGroup().getThumbnails() != null
				&& videoEntry.getMediaGroup().getThumbnails().size() > 1) {
			this.thumbImageUrl = (new Text(videoEntry.getMediaGroup()
					.getThumbnails().get(1).getUrl()));
		}
		this.title = (new Text(videoEntry.getMediaGroup().getTitle()
				.getPlainTextContent()));
		if (videoEntry.getMediaGroup().getDescription() != null) {
			this.description = (new Text(videoEntry.getMediaGroup()
					.getDescription().getPlainTextContent()));
		}
		this.alias = (new Text(StringHelper.getAliasByLanguage(this.getTitle()
				.getValue())));

		this.authorUrl = (videoEntry.getAuthors().get(0).getUri());
		if (videoEntry.getStatistics() != null) {
			this.viewCount = videoEntry.getStatistics().getViewCount();
		}
		if (videoEntry.getMediaGroup().getDuration() != null) {
			Long duration = videoEntry.getMediaGroup().getDuration();
			int hours = (int) (duration / 3600);
			int remainder = (int) (duration - hours * 3600);
			int minutes = remainder / 60;
			remainder = remainder - minutes * 60;
			int second = remainder;
			this.duration = (duration);
			this.totalTime = (new Text(((hours > 0) ? (hours + ":") : "")
					+ ((minutes > 9) ? minutes : ("0" + minutes)) + ":"
					+ ((second > 9) ? second : ("0" + second))));
		}

		// advanced.

		this.published = (new Date(videoEntry.getPublished().getValue()));
		JavaCacheHandle.initCache();
		if (videoEntry.getMediaGroup().getKeywords() != null) {
			List<Text> listKey = new ArrayList<Text>();
			for (String keyword : videoEntry.getMediaGroup().getKeywords()
					.getKeywords()) {
				Tag tmpTag = null;
				listKey.add(new Text(keyword));
				String tagAlias = keyword;
				tmpTag = TagModel.getByAlias(tagAlias);
				List<Text> listTubeId = new ArrayList<Text>();
				if (tmpTag != null) {
					tmpTag.setCount(tmpTag.getCount() + 1);
					listTubeId.addAll(tmpTag.getListTubeId());
					listTubeId.add(new Text(this.tubeId));
					tmpTag.setListTubeId(listTubeId);
					TagModel.update(tmpTag);
					TagModel.closePM();
				} else {
					tmpTag = new Tag();
					listTubeId.add(new Text(this.tubeId));
					tmpTag.setListTubeId(listTubeId);
					tmpTag.setAlias(tagAlias);
					tmpTag.setCount(1);
					tmpTag.setTitle(new Text(tagAlias));
					TagModel.add(tmpTag);
				}
			}
			this.keywords = listKey;
			JavaCacheHandle.addKeywords(listKey);
		}

		// get other tag.
		this.otherKeywords = JavaCacheHandle.getRandomKeywords();

		if (videoEntry.getStatistics() != null) {
			this.viewCount = videoEntry.getStatistics().getViewCount();
		}
		this.status = (1);
		this.updated = (Calendar.getInstance().getTime());
	}
}
